applyメソッド:一般的な分離 - 適用 - 結合の方法
最も一般的な目的を持つGroupByのメソッドはapplyです。applyはオブジェクトを操作するためのピースに分類し、それぞれのピースに対して渡された関数を適用し、その後それらのピースを結合します。
code: Python
import pandas as pd
tips = pd.read_csv('tips.csv')
# 総支払額に占めるチップの割合を追加
--------------------------------------------------------------------------
total_bill tip smoker day time size tip_pct
0 16.99 1.01 No Sun Dinner 2 0.059447
1 10.34 1.66 No Sun Dinner 3 0.160542
2 21.01 3.50 No Sun Dinner 3 0.166587
3 23.68 3.31 No Sun Dinner 2 0.139780
4 24.59 3.61 No Sun Dinner 4 0.146808
5 25.29 4.71 No Sun Dinner 4 0.186240
--------------------------------------------------------------------------
特定の列の上位の値を持つ行を選択する関数を定義します。
code: Python
def top(df, n=5, column='tip_pct'):
return df.sort_values(by=column)-n: top(tips, n=6)
--------------------------------------------------------------------------
total_bill tip smoker day time size tip_pct
109 14.31 4.00 Yes Sat Dinner 2 0.279525
183 23.17 6.50 Yes Sun Dinner 4 0.280535
232 11.61 3.39 No Sat Dinner 2 0.291990
67 3.07 1.00 Yes Sat Dinner 1 0.325733
178 9.60 4.00 Yes Sun Dinner 2 0.416667
172 7.25 5.15 Yes Sun Dinner 2 0.710345
--------------------------------------------------------------------------
smoker列でグループ分けし、applyメソッドを使って上のtop関数を適用すると、次のような結果になります。top関数はデータフレームの各行グループに対して呼ばれ、結果がpandas.concatで結合され、それぞれのグループに名前が付きます。したがって内部の階層にもともとのデータフレームのインデックス値を持っています。
code: Python
tips.groupby('smoker').apply(top)
--------------------------------------------------------------------------
total_bill tip smoker day time size tip_pct
smoker
No 88 24.71 5.85 No Thur Lunch 2 0.236746
185 20.69 5.00 No Sun Dinner 5 0.241663
51 10.29 2.60 No Sun Dinner 2 0.252672
149 7.51 2.00 No Thur Lunch 2 0.266312
232 11.61 3.39 No Sat Dinner 2 0.291990
Yes 109 14.31 4.00 Yes Sat Dinner 2 0.279525
183 23.17 6.50 Yes Sun Dinner 4 0.280535
67 3.07 1.00 Yes Sat Dinner 1 0.325733
178 9.60 4.00 Yes Sun Dinner 2 0.416667
172 7.25 5.15 Yes Sun Dinner 2 0.710345
--------------------------------------------------------------------------
引数やキーワードが必要な関数をapplyに渡す場合でも、その関数の後にそれらの引数を指定することができます。
code: Python
--------------------------------------------------------------------------
total_bill tip smoker day time size tip_pct
smoker day
No Fri 94 22.75 3.25 No Fri Dinner 2 0.142857
Sat 212 48.33 9.00 No Sat Dinner 4 0.186220
Sun 156 48.17 5.00 No Sun Dinner 6 0.103799
Thur 142 41.19 5.00 No Thur Lunch 5 0.121389
Yes Fri 95 40.17 4.73 Yes Fri Dinner 4 0.117750
Sat 170 50.81 10.00 Yes Sat Dinner 3 0.196812
Sun 182 45.35 3.50 Yes Sun Dinner 3 0.077178
Thur 197 43.11 5.00 Yes Thur Lunch 4 0.115982
--------------------------------------------------------------------------
グループ固有の値で欠損値を埋める
code: Python
s = pd.Series(np.random.randn(6))
s
--------------------------------------------------------------------------
0 NaN
1 -0.125921
2 NaN
3 -0.884475
4 NaN
5 0.227290
dtype: float64
--------------------------------------------------------------------------
code: Python
s.fillna(s.mean())
--------------------------------------------------------------------------
0 -0.261035
1 -0.125921
2 -0.261035
3 -0.884475
4 -0.261035
5 0.227290
dtype: float64
--------------------------------------------------------------------------
code: Python
states = ['Ohio', 'New York', 'Vermont', 'Florida',
'Oregon', 'Nevada', 'California', 'Idaho']
data = pd.Series(np.random.randn(8), index=states)
data
--------------------------------------------------------------------------
Ohio 0.922264
New York -2.153545
Vermont -0.365757
Florida -0.375842
Oregon 0.329939
Nevada 0.981994
California 1.105913
Idaho -1.613716
dtype: float64
--------------------------------------------------------------------------
code: Python
data'Vermont', 'Nevada', 'Idaho' = np.nan
data
--------------------------------------------------------------------------
Ohio 0.922264
New York -2.153545
Vermont NaN
Florida -0.375842
Oregon 0.329939
Nevada NaN
California 1.105913
Idaho NaN
dtype: float64
--------------------------------------------------------------------------
code: Python
data.groupby(group_key).mean()
--------------------------------------------------------------------------
East -0.535707
West 0.717926
dtype: float64
--------------------------------------------------------------------------
欠損値をグループの平均値で埋める。
code: Python
fill_mean = lambda g: g.fillna(g.mean())
data.groupby(group_key).apply(fill_mean)
--------------------------------------------------------------------------
Ohio 0.922264
New York -2.153545
Vermont -0.535707
Florida -0.375842
Oregon 0.329939
Nevada 0.717926
California 1.105913
Idaho 0.717926
dtype: float64
--------------------------------------------------------------------------
code: Python
fill_values = {'East': 0.5, 'West': -1}
fill_func = lambda g: g.fillna(fill_valuesg.name) data.groupby(group_key).apply(fill_func)
--------------------------------------------------------------------------
Ohio 0.922264
New York -2.153545
Vermont 0.500000
Florida -0.375842
Oregon 0.329939
Nevada -1.000000
California 1.105913
Idaho -1.000000
dtype: float64
--------------------------------------------------------------------------